package com.tianji.learning.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.enums.PointsRecordType;
import com.tianji.learning.pojo.po.PointsRecord;
import com.tianji.learning.mapper.PointsRecordMapper;
import com.tianji.learning.pojo.vo.PointsStatisticsVO;
import com.tianji.learning.service.IPointsRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.tianji.common.utils.DateUtils.POINTS_BOARD_SUFFIX_FORMATTER;

/**
 * <p>
 * 学习积分记录，每个月底清零 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-11-10
 */
@Service
@RequiredArgsConstructor
public class PointsRecordServiceImpl extends ServiceImpl<PointsRecordMapper, PointsRecord> implements IPointsRecordService {

    private final StringRedisTemplate redisTemplate;

    @Override
    public void addPointsRecord(Long userId, Integer points, PointsRecordType type) {
        LocalDateTime now = LocalDateTime.now();
        int maxPoints = type.getMaxPoints();

        // 判断当前方式有没有积分上限
        int realPoints = points;
        if (maxPoints > 0) {

            LocalDateTime begin = DateUtils.getDayStartTime(now);
            LocalDateTime end = DateUtils.getDayEndTime(now);

            // 查询今天已获得的积分
            LambdaQueryChainWrapper<PointsRecord> wrapper = lambdaQuery()
                    .eq(PointsRecord::getUserId, userId)
                    .eq(type != null, PointsRecord::getType, type)
                    .between(PointsRecord::getCreateTime, begin, end);

            Integer currentPoints = getBaseMapper().queryUserPointsByTypeAndDate(wrapper);
            if (null == currentPoints) {
                currentPoints = 0;
            }

            // 判断是否超过上限
            if (currentPoints >= maxPoints) {
                // 超过直接结束
                return;
            }

            // 如果总和超过限制，增加的是差值
            if (currentPoints + points > maxPoints) {
                realPoints = maxPoints - currentPoints;
            }
        }

        PointsRecord pointsRecord = new PointsRecord();
        pointsRecord.setPoints(realPoints);
        pointsRecord.setUserId(userId);
        pointsRecord.setType(type);
        save(pointsRecord);

        // 更新积分到缓存
        String key = RedisConstants.POINT_BOARD_KEY_PREFIX + now.format(POINTS_BOARD_SUFFIX_FORMATTER);
        redisTemplate.opsForZSet().incrementScore(key, userId.toString(), realPoints);
    }

    @Override
    public List<PointsStatisticsVO> queryMyPointsToday() {
        // 查询今日我的积分信息列表
        Long userId = UserContext.getUser();
        LocalDateTime begin = DateUtils.getDayStartTime(LocalDateTime.now());
        LocalDateTime end = DateUtils.getDayEndTime(LocalDateTime.now());

        LambdaQueryChainWrapper<PointsRecord> wrapper = lambdaQuery()
                .eq(PointsRecord::getUserId, userId)
                .between(PointsRecord::getCreateTime, begin, end);

        List<PointsRecord> list = getBaseMapper().queryUserPointsByDate(wrapper);
        if (CollUtil.isEmpty(list)) {
            return CollUtils.emptyList();
        }

        List<PointsStatisticsVO> vos = new ArrayList<>(list.size());
        for (PointsRecord record : list) {
            PointsStatisticsVO vo = new PointsStatisticsVO();
            vo.setType(record.getType().getDesc());
            vo.setMaxPoints(record.getType().getMaxPoints());
            vo.setPoints(record.getPoints());
            vos.add(vo);
        }
        return vos;
    }
}
